<template>
  <div class="query-container">
    <el-card class="query-card">
      <template #header>
        <div class="card-header">
          <div class="header-left">
            <span class="title">SQL查询</span>
            <el-select v-model="selectedConnection" placeholder="请选择数据库连接" @change="handleConnectionChange">
              <el-option
                v-for="item in connectionList"
                :key="item.id"
                :label="item.sqlName"
                :value="item.id"
                :disabled="item.status !== 1"
              >
                <span>{{ item.sqlName }}</span>
                <span class="connection-info">
                  ({{ item.username }}@{{ item.ip }}:{{ item.port }})
                </span>
              </el-option>
            </el-select>
          </div>
          <div class="header-actions">
            <el-button-group>
              <el-button type="primary" @click="handleExecute" :disabled="!selectedConnection || !sqlContent">
                <el-icon><VideoPlay /></el-icon>执行
              </el-button>
              <el-button type="warning" @click="handleClear">
                <el-icon><Delete /></el-icon>清空
              </el-button>
            </el-button-group>
          </div>
        </div>
      </template>

      <splitpanes horizontal style="height: calc(100vh - 160px); min-height: 400px;">
        <pane min-size="10" size="30">
          <!-- SQL编辑器区域 -->
          <div class="editor-container">
            <div class="sql-editor">
              <el-input
                v-model="sqlContent"
                type="textarea"
                :rows="8"
                placeholder="请输入SQL语句..."
                resize="vertical"
              />
            </div>
          </div>
        </pane>
        <pane min-size="10" size="70">
          <!-- 查询结果区域 -->
          <div class="result-container" v-loading="loading">
            <div v-if="error" class="error-message">
              <el-alert
                :title="error"
                type="error"
                :closable="false"
                show-icon
                style="white-space: pre-wrap; word-break: break-all;"
              />
            </div>
            <div v-else class="results-wrapper">
              <!-- 非查询操作结果 -->
              <div v-if="updateResults.length > 0" class="update-results">
                <el-alert
                  v-for="result in updateResults"
                  :key="result.id"
                  :title="result.sql"
                  :description="result.message"
                  type="success"
                  :closable="false"
                  show-icon
                />
              </div>
              <!-- 查询结果标签页 -->
              <div v-if="queryResults.length > 0" class="query-results">
                <el-tabs 
                  v-model="activeTab" 
                  type="border-card" 
                  class="query-tabs"
                >
                  <el-tab-pane
                    v-for="(result, index) in queryResults"
                    :key="'query-'+index"
                    :label="'查询结果 ' + (index + 1)"
                    :name="String(index)"
                  >
                    <div class="query-result">
                      <div v-if="showSqlTip" class="sql-statement">
                        <div class="sql-label">执行SQL:</div>
                        <div class="sql-content">{{ result.sql }}</div>
                      </div>
                      <div class="table-wrapper" v-if="result.type === 'select'">
                        <el-table
                          :data="result.data"
                          border
                          style="width: 100%;"
                          max-height="540px"
                          scrollbar-always-on
                        >
                          <!-- ID列固定在第一列 -->
                          <el-table-column
                            prop="id"
                            label="id"
                            width="80"
                            fixed="left"
                            align="center"
                          />
                          <!-- 其他列 -->
                          <el-table-column
                            v-for="column in result.columns.filter(col => col !== 'id')"
                            :key="column"
                            :prop="column"
                            :label="column"
                            show-overflow-tooltip
                            min-width="150"
                          >
                            <template #default="scope">
                              <div 
                                class="cell-content" 
                                @click="handleCellClick(result.sql, scope.row, column)"
                                style="cursor: pointer;"
                              >
                                {{ formatCellValue(scope.row[column]) }}
                              </div>
                            </template>
                          </el-table-column>
                        </el-table>
                        <!-- 分页控件 -->
                        <el-pagination
                          v-if="result.type === 'select' && pagination.total > pagination.size"
                          style="margin-top: 16px; text-align: right;"
                          background
                          layout="total, sizes, prev, pager, next, jumper"
                          :total="pagination.total"
                          :page-size="pagination.size"
                          :current-page="pagination.current"
                          :page-sizes="[10, 20, 50, 100]"
                          @current-change="handlePageChange"
                          @size-change="handleSizeChange"
                        />
                      </div>
                    </div>
                  </el-tab-pane>
                </el-tabs>
              </div>
            </div>
          </div>
        </pane>
      </splitpanes>

      <!-- 编辑对话框 -->
      <el-dialog
        v-model="editDialogVisible"
        :title="'编辑数据'"
        width="500px"
        :close-on-click-modal="false"
        append-to-body
      >
        <el-form
          ref="editFormRef"
          :model="editForm"
          label-width="100px"
        >
          <el-form-item :label="editForm.columnName">
            <template v-if="editForm.columnType === 'timestamp'">
              <el-date-picker
                v-model="editForm.value"
                type="datetime"
                :placeholder="'请选择' + editForm.columnName"
                style="width: 100%"
                format="YYYY-MM-DD HH:mm:ss"
                value-format="YYYY-MM-DD HH:mm:ss"
              />
            </template>
            <template v-else-if="['int2', 'int4', 'int8'].includes(editForm.columnType)">
              <el-input-number
                v-model="editForm.value"
                :placeholder="'请输入' + editForm.columnName"
                style="width: 100%"
              />
            </template>
            <template v-else>
              <el-input
                v-model="editForm.value"
                :type="isLongText(editForm.value) ? 'textarea' : 'text'"
                :rows="isLongText(editForm.value) ? 4 : 1"
                :placeholder="'请输入' + editForm.columnName"
              />
            </template>
          </el-form-item>
        </el-form>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="editDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="handleSaveEdit">确定</el-button>
          </span>
        </template>
      </el-dialog>
    </el-card>
  </div>
</template>

<script setup>
import { ref, onMounted, reactive } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import axios from 'axios'
import { VideoPlay, Delete, Download } from '@element-plus/icons-vue'
import { useRoute } from 'vue-router'
import { useUserStore } from '@/stores/user'
import { Splitpanes, Pane } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'

const route = useRoute()
const userStore = useUserStore()
const connectionList = ref([])
const selectedConnection = ref(null)
const sqlContent = ref('')
const loading = ref(false)
const error = ref('')
const updateResults = ref([])
const queryResults = ref([])
const activeTab = ref('0')

// 编辑相关的响应式变量
const editDialogVisible = ref(false)
const editFormRef = ref(null)
const editForm = reactive({
  columnName: '',
  columnType: '',
  value: '',
  columnId: null,
  tableName: '',
  sql: ''
})

const pagination = ref({
  current: 1,
  size: 10,
  total: 0
})

const showSqlTip = ref(false)

// 自动清除更新结果提示
const autoRemoveUpdateResult = (result) => {
  setTimeout(() => {
    const index = updateResults.value.indexOf(result)
    if (index > -1) {
      updateResults.value.splice(index, 1)
    }
  }, 2000)
}

// 获取连接列表
const fetchConnectionList = async () => {
  try {
    const response = await axios.get('/api/connection/list')
    if (response.data.code === '200') {
      connectionList.value = response.data.data.data || []
    } else {
      ElMessage.error(response.data.message || '获取连接列表失败')
    }
  } catch (error) {
    console.error('获取连接列表失败:', error)
    ElMessage.error('获取连接列表失败')
  }
}

// 判断SQL类型
const getSqlType = (sql) => {
  const trimmedSql = sql.trim()
  if (trimmedSql.startsWith('select')) return 4
  if (trimmedSql.startsWith('insert')) return 1
  if (trimmedSql.startsWith('update')) return 3
  if (trimmedSql.startsWith('delete')) return 2
  if (trimmedSql.startsWith('CREATE')) return 5
  if (trimmedSql.startsWith('DROP')) return 6
  return null
}

// 执行单条SQL
const executeSingleSql = async (sql, operation, current = 1, size = 10) => {
  try {
    const userInfo = JSON.parse(localStorage.getItem('user') || '{}')
    if (!userInfo.id) {
      ElMessage.error('用户未登录')
      return {
        success: false,
        message: '用户未登录'
      }
    }

    let url = `/api/connection/${userInfo.id}/${selectedConnection.value}/${operation}`
    let data = { sql, current, size }
    let config = { headers: { 'Content-Type': 'application/json' } }

    const response = await axios.post(url, data, config)

    if (response.data.code === '200') {
      if (operation === 4) { // SELECT
        const pageInfo = response.data.data || {}
        let data = pageInfo.records || []
        let columns = []
        if (data.length > 0) {
          columns = Object.keys(data[0])
        }
        // 设置分页信息
        pagination.value.current = pageInfo.currentPage || 1
        pagination.value.size = pageInfo.pageSize || 10
        pagination.value.total = pageInfo.totalRecords || 0
        return {
          success: true,
          type: 'select',
          sql,
          data,
          columns
        }
      } else {
        let message = response.data.message || '操作成功'
        if (operation === 5) {
          message = '创建成功'
        } else if (operation === 6) {
          message = '删除成功'
        }
        return {
          success: true,
          type: 'update',
          sql,
          message
        }
      }
    } else {
      return {
        success: false,
        message: response.data.message || '操作失败'
      }
    }
  } catch (err) {
    console.error('执行SQL失败:', err)
    return {
      success: false,
      message: err.response?.data?.message || '执行SQL失败'
    }
  }
}

// 执行SQL
const handleExecute = async (page = 1, size = 10) => {
  if (!selectedConnection.value || !sqlContent.value) {
    ElMessage.warning('请选择数据库连接并输入SQL语句')
    return
  }

  loading.value = true
  error.value = ''
  updateResults.value = []
  queryResults.value = []
  activeTab.value = '0'

  try {
    // 分割SQL语句
    const statements = sqlContent.value
      .split(';')
      .map(sql => sql.trim())
      .filter(sql => sql.length > 0)

    if (statements.length === 0) {
      ElMessage.warning('请输入有效的SQL语句')
      return
    }

    // 依次执行每条SQL
    for (const sql of statements) {
      const operation = getSqlType(sql)
      if (!operation) {
        error.value = `不支持的SQL操作类型: ${sql}`
        ElMessage.error(error.value)
        return
      }
      // 只对select传分页参数
      const result = await executeSingleSql(sql, operation, pagination.value.current, pagination.value.size)
      if (!result.success) {
        error.value = `SQL执行失败: ${result.message}\nSQL: ${sql}`
        ElMessage.error(error.value)
      } else {
        if (result.type === 'select') {
          queryResults.value.push(result)
          showSqlTip.value = true
          setTimeout(() => {
            showSqlTip.value = false
          }, 2000)
          ElMessage.success('查询执行成功')
        } else {
          const updateResult = {
            ...result,
            id: Date.now() + Math.random() // 添加唯一标识
          }
          updateResults.value.push(updateResult)
          autoRemoveUpdateResult(updateResult)
          ElMessage.success(result.message || '执行成功')
        }
      }
    }
  } catch (err) {
    console.error('执行SQL失败:', err)
    error.value = err.message || '执行SQL失败'
    ElMessage.error(error.value)
  } finally {
    loading.value = false
  }
}

// 清空
const handleClear = () => {
  sqlContent.value = ''
  error.value = ''
  updateResults.value = []
  queryResults.value = []
  activeTab.value = '0'
}

// 切换数据库连接
const handleConnectionChange = () => {
  error.value = ''
  updateResults.value = []
  queryResults.value = []
  activeTab.value = '0'
}

// 添加导出功能
const handleExport = async () => {
  if (!selectedConnection.value) {
    ElMessage.warning('请选择数据库连接')
    return
  }

  try {
    loading.value = true
    const sql = sqlContent.value.trim()
    
    // 从SQL中提取表名
    const match = sql.match(/from\s+(\w+)/i)
    if (!match) {
      ElMessage.warning('无法获取表名，请确保SQL语句包含FROM子句')
      return
    }
    const tableName = match[1].trim()

    const response = await axios.get('/api/connection/tableData', {
      params: {
        connectionId: selectedConnection.value,
        tableName: tableName,
        current: 1,
        size: 1000, // 导出更多数据
        export: 1
      },
      responseType: 'blob'
    })

    // 创建下载链接
    const url = window.URL.createObjectURL(new Blob([response.data]))
    const link = document.createElement('a')
    link.href = url
    const filename = `${tableName}_${new Date().toISOString().split('T')[0]}`
    link.setAttribute('download', `${filename}.xlsx`)
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)

    ElMessage.success('导出成功')
  } catch (error) {
    console.error('导出失败:', error)
    ElMessage.error('导出失败')
  } finally {
    loading.value = false
  }
}

// 格式化单元格显示值
const formatCellValue = (value) => {
  if (value === null || value === undefined) return '';
  if (typeof value === 'object') {
    // 如果是时间戳，转换为日期字符串
    if (value instanceof Date || (typeof value === 'number' && value > 1000000000000)) {
      return new Date(value).toLocaleString()
    }
    return JSON.stringify(value)
  }
  return String(value)
}

// 判断是否为长文本
const isLongText = (text) => {
  return typeof text === 'string' && text.length > 100
}

// 处理单元格点击
const handleCellClick = async (sql, row, column) => {
  // 从 SQL 中提取表名
  const match = sql.match(/from\s+(\w+)/i);
  const tableName = match ? match[1].trim() : null;
  
  if (!tableName) {
    ElMessage.error('无法获取表名');
    return;
  }

  try {
    // 获取字段类型
    const response = await axios.get(`/api/connection/${selectedConnection.value}/tableDataType`, {
      params: {
        tableName: tableName,
        columnName: column
      }
    });

    if (response.data.code === '200') {
      editForm.sql = sql;
      editForm.tableName = tableName;
      editForm.columnName = column;
      editForm.columnType = response.data.data;
      editForm.value = row[column];
      editForm.columnId = row.id;
      
      editDialogVisible.value = true;
    } else {
      ElMessage.error(response.data.message || '获取字段类型失败');
    }
  } catch (error) {
    console.error('获取字段类型失败:', error);
    ElMessage.error('获取字段类型失败');
  }
};

// 处理保存编辑
const handleSaveEdit = async () => {
  try {
    let columnValue = editForm.value
    if (columnValue === null || columnValue === undefined) {
      columnValue = ''
    } else {
      columnValue = columnValue.toString()
    }
    
    // 如果是时间戳类型，强制转换为YYYY-MM-DD HH:mm:ss格式
    if (editForm.columnType === 'timestamp' && editForm.value) {
      try {
        // 将日期字符串转换为Date对象
        const date = new Date(editForm.value)
        if (isNaN(date.getTime())) {
          throw new Error('无效的日期格式')
        }
        // 格式化为YYYY-MM-DD HH:mm:ss
        const year = date.getFullYear()
        const month = String(date.getMonth() + 1).padStart(2, '0')
        const day = String(date.getDate()).padStart(2, '0')
        const hours = String(date.getHours()).padStart(2, '0')
        const minutes = String(date.getMinutes()).padStart(2, '0')
        const seconds = String(date.getSeconds()).padStart(2, '0')
        columnValue = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
      } catch (error) {
        console.error('日期转换失败:', error)
        ElMessage.error('日期格式无效')
        return
      }
    }

    const response = await axios.put(`/api/connection/${selectedConnection.value}/UpdateTableData`, {
      tableName: editForm.tableName,
      columnName: editForm.columnName,
      columnType: editForm.columnType,
      columnId: editForm.columnId,
      columnValue: columnValue
    })

    if (response.data.code === '200') {
      ElMessage.success('更新成功')
      editDialogVisible.value = false
      
      // 更新本地数据
      const resultIndex = queryResults.value.findIndex(r => r.sql === editForm.sql)
      if (resultIndex !== -1) {
        const rowIndex = queryResults.value[resultIndex].data.findIndex(item => item.id === editForm.columnId)
        if (rowIndex !== -1) {
          queryResults.value[resultIndex].data[rowIndex][editForm.columnName] = editForm.value
        }
      }
    } else {
      ElMessage.error(response.data.message || '更新失败')
    }
  } catch (error) {
    console.error('保存编辑失败:', error)
    ElMessage.error(error.response?.data?.message || '保存失败')
  }
}

// 分页切换
const handlePageChange = (page) => {
  pagination.value.current = page;
  handleExecute(page, pagination.value.size)
}
const handleSizeChange = (size) => {
  pagination.value.size = size;
  pagination.value.current = 1;
  handleExecute(1, size)
}

onMounted(() => {
  fetchConnectionList()
})
</script>

<style scoped>
.query-container {
  height: 100%;
  padding: 16px;
  box-sizing: border-box;
}

.query-card {
  height: 100%;
  display: flex;
  flex-direction: column;
}

:deep(.el-card__body) {
  flex: 1;
  padding: 16px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 16px;
}

.title {
  font-size: 16px;
  font-weight: 500;
}

.header-actions {
  display: flex;
  gap: 12px;
}

.editor-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow: hidden;
}

.sql-editor {
  min-height: 120px;
}

:deep(.el-textarea__inner) {
  font-family: monospace;
  font-size: 14px;
  line-height: 1.5;
  padding: 12px;
}

.result-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.results-wrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow: hidden;
  position: relative;
}

.update-results {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

:deep(.el-alert) {
  transition: all 0.3s ease-in-out;
}

.query-results {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.query-tabs {
  flex: 1;
  display: flex;
  flex-direction: column;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;
}

:deep(.el-tabs__content) {
  flex: 1;
  padding: 16px;
  overflow: hidden;
}

.query-result {
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.sql-statement {
  background-color: #f5f7fa;
  border-radius: 4px;
  padding: 12px;
  border-left: 4px solid #409eff;
}

.sql-label {
  font-weight: 500;
  margin-bottom: 8px;
  color: #606266;
}

.sql-content {
  font-family: monospace;
  font-size: 14px;
  white-space: pre-wrap;
  word-break: break-all;
}

.table-wrapper {
  padding-bottom: 0;
}

:deep(.el-table) {
  --el-table-header-bg-color: #f5f7fa;
}

:deep(.el-table th) {
  font-weight: 600;
}

:deep(.el-table .cell) {
  white-space: nowrap;
}

.error-message {
  margin-bottom: 16px;
}

:deep(.el-select) {
  width: 300px;
}

/* 增强 splitpanes 分割线的可拖拽体验 */
.splitpanes__splitter {
  position: relative;
  height: 20px !important;      /* 可拖拽区域更大 */
  min-height: 20px !important;
  background: transparent !important;
  cursor: row-resize !important;
  z-index: 10;
}
.splitpanes__splitter::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 50%; transform: translateY(-50%);
  height: 6px;
  background: #e0e0e0;
  border-radius: 3px;
  box-shadow: 0 1px 4px rgba(64,158,255,0.15);
  transition: background 0.2s;
}
.splitpanes__splitter:hover::before {
  background: #409eff;
}
</style> 